Git 克隆 GitHub 报错 GnuTLS (-110) 解决

📂 运维学习

Git 克隆 GitHub 报错 GnuTLS (-110) 解决

一、问题场景

在 Ubuntu 云服务器使用 HTTPS 协议克隆 GitHub 私有/公开仓库,执行命令:

BASH
git clone https://github.com/timozhuai/727blog.git /var/www/727blog

持续报错:

GnuTLS recv error (-110): The TLS connection was non-properly terminated.

二、报错原因分析

  1. Ubuntu Git 默认使用 GnuTLS 做 SSL 握手,与 GitHub HTTPS 链路兼容性差,网络轻微抖动就会 TLS 异常中断。

  2. 云服务器公网环境容易出现链路不稳定,HTTPS 克隆极易断连、重试无效。

  3. 单纯重复git clone 重试无法解决,属于底层协议兼容性 bug,非临时网络波动。

三、最终解决方案:弃用 HTTPS,改用 SSH 协议克隆

SSH 不经过 GnuTLS 链路,握手更稳定,彻底规避该 TLS 报错。

步骤1:清理错误密钥(本次踩坑点)

初次生成密钥时误输入密码、注释文字,导致密钥生成失败、文件不存在,先清理脏文件:

BASH
rm -rf /root/.ssh/*

步骤2:重新生成 ED25519 密钥(全程无脑回车)

BASH
ssh-keygen -t ed25519

三次提示 全部直接回车

  • 保存路径:默认回车

  • 密钥密码:空(直接回车)

  • 确认密码:空(直接回车)

✅ 禁止输入任何文字、注释、密码,否则密钥生成异常。

步骤3:查看并复制公钥

BASH
cat /root/.ssh/id_ed25519.pub

复制整段以 ssh-ed25519 开头、服务器主机名结尾的公钥。

步骤4:GitHub 添加 SSH 公钥

GitHub 官网 → Settings → SSH and GPG keys → New SSH key
粘贴公钥、保存。

步骤5:测试 GitHub SSH 连通性

BASH
ssh -T git@github.com

返回 successfully authenticated 即配置成功。

步骤6:使用 SSH 地址克隆仓库(成功解决)

BASH
git clone git@github.com:timozhuai/727blog.git /var/www/727blog

四、关键后续:初始化 Git 子模块(本次项目必备)

git clone git@github.com:timozhuai/md_obsidian.git content
当前博客项目 727blog 的 content 目录是 md_obsidian 子模块,默认克隆后 content 为空,必须执行:

BASH
cd /var/www/727blog
git submodule update --init --recursive

✅ 作用:拉取子模块真实笔记内容,网站才能正常渲染。

五、本次踩坑复盘(重点记忆)

  1. GnuTLS recv error 不要盲目重试,是 Ubuntu Git 固有兼容问题,优先换 SSH 协议。

  2. ssh-keygen 生成密钥时,全程空回车,不要输任何内容,否则密钥损坏。

  3. 带 submodule 的仓库,克隆后必须手动初始化子模块,否则核心内容缺失。

  4. HTTPS 适合本地带代理场景,云服务器 GitHub 操作优先 SSH,稳定零报错。

六、临时备选方案(不推荐长期用)

若临时不想配置 SSH,可关闭证书校验临时绕过:

BASH
git config --global http.sslVerify false

缺点:不安全,仅调试使用,生产不建议。

(注:部分内容可能由 AI 生成)

问题总结

环境:Ubuntu云服务器,项目使用git submodule,子模块 content 指向 timozhuai/md_obsidian.git

遇到的全部问题

  1. dubious ownership 可疑仓库报错:root 用户操作其他用户仓库,但文件属主不匹配Git安全校验。
    • 解决:git config --global --add safe.directory '*',放行git目录所有权检查。
  2. 子模块HTTPS克隆443超时:服务器curl可以访问github首页,但git clone https长连接丢包超时,云服务器出口网络问题。
  3. 尝试切换SSH拉取踩坑:
    • ①子模块未初始化,git config submodule.content.url 直接修改子模块url不生效
    • ②直接修改 .gitmodules + git submodule sync,未初始化子模块sync无效,容易误提交SSH地址到远程仓库;
    • ③首次SSH连接github,需要手动输入yes写入known_hosts主机指纹;
    • Permission denied (publickey):ubuntu普通用户的SSH私钥未正确配置,公钥没有添加到GitHub;
    • ⑤HTTPS协议填账号密码报错:Github不再支持账号密码登录,只能用token。

最终可行解决流程

手动ssh克隆子模块目录,绕开submodule自带的clone逻辑,再执行子模块初始化。

# 1.清理旧的残留
rm -rf content
rm -rf .git/modules/content

# 2.手动ssh协议克隆子模块(本机ubuntu用户SSH密钥配置完成,公钥已添加GitHub)
git clone git@github.com:timozhuai/md_obsidian.git content

# 3.执行子模块初始化更新,不会重复克隆,仅对齐commit版本
git submodule update --init --recursive

关键知识点

  1. git submodule update --init --recursive 在子模块目录不存在时,会自动执行clone;目录已经存在,则只做版本校验,不再发起网络克隆。
  2. .gitmodules 记录的是公共推荐地址,不要随意改成SSH提交到仓库,否则其他没有配置SSH密钥的人会拉取失败。
  3. git config submodule.xxx.url 仅对子模块已经初始化完成才生效,空白未初始化子模块该命令无效。
  4. insteadOf 全局url替换可以全局把https github地址转ssh,但前提SSH密钥必须完全可用。

后续日常维护命令

# 以后拉取主仓库更新,同步更新子模块
git pull
git submodule update --recursive

注意:以后提交主仓库代码,.gitmodules 保持原始https地址不变,不要提交ssh格式url。

vim不能创建目录 能创建文件
进入 vim 后,先敲 :set paste 回车(关闭自动缩进,粘贴不乱)

Ubuntu‑Debian Nginx sites‑available / sites‑enabled 特有机制总结

CentOS没有这套,直接用conf.d/*.conf

  1. sites‑available:配置仓库 存放全部站点配置文件。写在这里不会生效,只是保存你的配置。允许不带.conf
  2. sites‑enabled:启用开关目录 Nginx 真正读取加载的目录。不存放真实配置,只放软链接(快捷方式)
  3. 启用站点:ln -s 创建软链接sites‑available 里的配置,在 sites‑enabled 创建快捷方式。Nginx reload 就会加载。
sudo ln -s /etc/nginx/sites-available/xxx /etc/nginx/sites-enabled/
  1. 关闭站点:只删软链接
sudo rm /etc/nginx/sites-enabled/xxx

仅删除快捷方式,原始配置仍然保存在 sites‑available,后续可再次链接启用。

  1. 固定工作流 编辑配置 → 存入 sites‑availableln -s 做软链接到 sites‑enablednginx -t校验语法 → systemctl reload nginx 生效。
  2. 核心优点
  • 开启/关闭站点不用复制、移动文件;
  • 原始配置始终保留,切换方便;
  • 所有修改统一在sites‑available,避免误改sites‑enabled
  1. 高频踩坑点
  • 配置写好了,但忘记ln -s,配置完全不生效;
  • ln命令源、目标写反,生成损坏链接;
  • 创建链接后不做nginx -t,配置语法错误会导致Nginx启动失败。

一句话记忆:available存稿子,enabled放快捷方式,软链接控制开关

nslookup mozhuai.site
查看DNS解析是否正确